package com.zjhcsoft.common.service.upload;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Calendar;
import java.util.Iterator;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;

import org.apache.log4j.Logger;

import com.sun.image.codec.jpeg.ImageFormatException;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import com.zjhcsoft.common.object.UploadObj;
import com.zjhcsoft.common.object.UploadPathObj;
import com.zjhcsoft.util.Config;

/**
 * 
 * @author SHARK create class 2012-03-25
 *
 */
public abstract class AbstractUploadFile {
	
	private static final Logger log = Logger.getLogger(AbstractUploadFile.class);
	
	/**
	 * 截图
	 */
	public static final int SUB_IMG = 1;
	
	/**
	 * 缩略图
	 */
	public static final int SMALL_IMG = 2;
	
	/**
	 * 正式上传文件
	 * @param input 文件流
	 * @param fileName 文件名
	 * @param model_path 模块路径
	 * @return 文件object
	 */
	protected UploadObj uploadFile(InputStream input,String fileName,String model_path) {
		// TODO Auto-generated method stub
		UploadPathObj pathObj = getUploadFilePath(fileName,model_path);
		String path = pathObj.getRealPath();
		File newFile = new File(path);
		
		try {
            InputStream in = null;  
            OutputStream out = null;  
            try {
                in = input;  
                out = new BufferedOutputStream(new FileOutputStream(newFile));
                byte[] buffer = new byte[1024];
                log.debug("正在上传文件 :"+fileName);
                int size = 0;
                while ((size = in.read(buffer)) != -1) {
                	out.write(buffer, 0, size);
                }
            }catch (Exception e){
            	log.debug("上传文件出错" + e.getMessage());
            	e.printStackTrace();
            }
            finally {
                if (null != in) {
                    in.close();
                }
                if (null != out) {
                    out.close();
                }
            }
        }
        catch (Exception e) {
        	log.debug("上传文件出错" + e.getMessage());
            e.printStackTrace();  
        }
        UploadObj obj = new UploadObj(fileName);
        obj.setPath(pathObj.getRealPath());
        obj.setRelativePath(pathObj.getRelativePath());
        return obj;
	}
	
	/**
	 * 判断是不是图片
	 * @param fileName 文件后缀名
	 * @return
	 */
	protected boolean isImg(String ext){
		boolean flag = false;
		ext = ext.toLowerCase();
		String type = Config.getString("upload.type");
		int index = type.indexOf(ext);
		if (index > 0){
			flag = true;
		}
		return flag;
	}
	
	/**
	 * 创建小图(截图)
	 * @param file 原图文件
	 * @param x 从x坐标哪个地方开始
	 * @param y 从y坐标哪个地方开始
	 * @param wid 长度
	 * @param heig 高度
	 * @return 切图路径对象
	 * @throws IOException
	 */
	protected UploadPathObj createCutImg(File file,int x,int y,int wid ,int heig) throws IOException{
		Iterator<ImageReader> readers = ImageIO.getImageReadersByFormatName("jpg");
		ImageReader reader = readers.next();
		InputStream source = new FileInputStream(file);
		ImageInputStream iis = ImageIO.createImageInputStream(source);
		reader.setInput(iis, true);
		ImageReadParam param = reader.getDefaultReadParam();
		Rectangle rect = new Rectangle(x, y, wid, heig);
		param.setSourceRegion(rect);
		BufferedImage bi = reader.read(0, param);
		File childFile = new File(tansferPath(file.getParentFile().getPath()) + "/" + "cut");
		if (!childFile.exists()){
			childFile.mkdir();
		}
		FileOutputStream out = new FileOutputStream(tansferPath(childFile.getPath()) + "/" + "cut.jpg");
		ImageIO.write(bi, "jpg", out);
		out.close();
		String cutPath = tansferPath(childFile.getPath()) + "/" + "cut.jpg";
		String relativeCutPath = cutPath.substring(Config.getString("upload.path").length());
		UploadPathObj obj = new UploadPathObj();
		obj.setRealPath(cutPath);
		obj.setRelativePath(relativeCutPath);
		return obj;
	}
	
	/**
	 * 创建小图
	 * @param file 原图文件
	 * @return 小图路径对象
	 * @throws IOException 
	 */
	protected UploadPathObj createSmallImg(File file) throws IOException{
		Image img = ImageIO.read(file);
		int wid = img.getWidth(null);
		int heig = img.getHeight(null);
		String smallPath = createSmallImg(tansferPath(file.getParentFile().getPath()),img, wid/2, heig/2);
		String relativeSmallPath = smallPath.substring(Config.getString("upload.path").length());
		UploadPathObj obj = new UploadPathObj();
		obj.setRealPath(smallPath);
		obj.setRelativePath(relativeSmallPath);
		return obj;
	}
	
	/**
	 * 创建小图
	 * @param file
	 * @param wid
	 * @param heig
	 * @return 小图路径对象
	 * @throws IOException
	 */
	protected UploadPathObj createSmallImg(File file,int wid ,int heig) throws IOException{
		Image img = ImageIO.read(file);
		String smallPath = createSmallImg(tansferPath(file.getParentFile().getPath()),img, wid, heig);
		String relativeSmallPath = smallPath.substring(Config.getString("upload.path").length());
		UploadPathObj obj = new UploadPathObj();
		obj.setRealPath(smallPath);
		obj.setRelativePath(relativeSmallPath);
		return obj;
	}
	
	
	
	/**
	 * 创建小图
	 * @param img 图片类型文件
	 * @return 小图路径对象
	 * @throws IOException 
	 * @throws ImageFormatException 
	 */
	protected UploadPathObj createSmallImg(String path ,Image img) throws ImageFormatException, IOException{
		int wid = img.getWidth(null);
		int heig = img.getHeight(null);
		String smallPath = createSmallImg(path ,img,wid/2,heig/2);
		String relativeSmallPath = smallPath.substring(Config.getString("upload.path").length());
		UploadPathObj obj = new UploadPathObj();
		obj.setRealPath(smallPath);
		obj.setRelativePath(relativeSmallPath);
		return obj;
	}
	
	/**
	 * 根据图片尺寸等比例创建小图
	 * @param img 图片类型文件
	 * @return 小图尺寸
	 * @throws IOException 
	 * @throws ImageFormatException 
	 */
	protected UploadPathObj createSmallImg(File file,int length ) throws IOException{
		Image img = ImageIO.read(file);
		UploadPathObj obj = createSmallImg(tansferPath(file.getParentFile().getPath()),img, length);
		return obj;
	}
	
	/**
	 * 根据图片尺寸等比例创建小图
	 * @param img 图片类型文件
	 * @return 小图路径对象
	 * @throws IOException 
	 * @throws ImageFormatException 
	 */
	protected UploadPathObj createSmallImg(String path ,Image img,int length) throws ImageFormatException, IOException{
		int wid = img.getWidth(null);
		int heig = img.getHeight(null);
		String smallPath="";
		if(wid>=heig){
			 smallPath = createSmallImg(path ,img,length,heig*length/wid);
		}else{
			 smallPath = createSmallImg(path ,img,wid*length/heig,length);
		}
		String relativeSmallPath = smallPath.substring(Config.getString("upload.path").length());
		UploadPathObj obj = new UploadPathObj();
		obj.setRealPath(smallPath);
		obj.setRelativePath(relativeSmallPath);
		return obj;
	}
	
	/**
	 * 
	 * 创建小图，需要根据设置好的长和高来创建
	 * @param path
	 * @param img 图片类型文件
	 * @param wid 宽
	 * @param heig 高
	 * @return 创建成功与否
	 * @return 小图路径实际路径
	 * @throws IOException 
	 * @throws ImageFormatException 
	 */
	protected String createSmallImg(String path,Image img,int wid ,int heig) throws ImageFormatException, IOException{
		BufferedImage bi = new BufferedImage(wid, heig, BufferedImage.TYPE_INT_RGB);
		Graphics2D g2d = bi.createGraphics();
		g2d.drawImage(img, 0,0,wid, heig, Color.white, null);
		g2d.dispose();
		File file = new File(path + "/" + "small");
		if (!file.exists()){
			file.mkdir();
		}
		FileOutputStream out = new FileOutputStream(tansferPath(file.getPath()) + "/" + "small.jpg");
		JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);   
		encoder.encode(bi);  
		out.close();
		return tansferPath(file.getPath()) + "/" + "small.jpg";
	}
	
	/**
	 * 得到后缀
	 * @param fileName 文件名
	 * @return 后缀
	 */
	protected String getFileExt(String fileName){
		int index = fileName.lastIndexOf(".");
		String ext = null;
		if (index == -1){
			return null;
		}else{
			if (index + 1 == fileName.length()){
				ext = null;
			}else{
				ext = fileName.substring(index + 1, fileName.length());
			}
		}
		return ext;
	}
	
	/**
	 * 得到真实的文件路径
	 * @param fileName 文件名
	 * @param model_path 模块路径
	 * @return 文件路径+新的文件名（随机生成的10位数作为名字，后缀不变）
	 */
	protected UploadPathObj getUploadFilePath(String fileName,String model_path) {
		UploadPathObj pathObj = getRealFilePath(model_path);
		String path = pathObj.getRealPath();
		String relativePath = pathObj.getRelativePath();
		String newFileName = null;
		String ext = getFileExt(fileName);
		String num = getRandomNumber();
		if (null != ext){
			newFileName = num + "." + ext;
		}else{
			newFileName = num + "";
		}
		String menuFilePath = getMenuFilePath(num ,path);
		//创建目录文件夹
		File newFile = new File(menuFilePath);
		if(!newFile.exists())
		{
			newFile.mkdirs();
		}
		String sub = menuFilePath.substring(path.length());
		relativePath = relativePath + sub;
		pathObj.setRealPath(menuFilePath + "/" + newFileName);
		pathObj.setRelativePath(relativePath + "/" + newFileName);
		//return getMenuFilePath(num ,path) + "/" + newFileName;
		//创建文件夹

		
		return pathObj;
	}
	
	/**
	 * 得到10位随机数
	 * @return 10位随机数
	 */
	private String getRandomNumber(){
		Random random = new Random();
//		random.setSeed(9999999999l);
		Integer no = random.nextInt();
		if (no < 0){
			no = no * -1;
		}
		String num = String.valueOf(no);
		if (num.length() < 10){
			int i = num.length();
			for (int m = 0; m < 10 -i ; m++){
				num = "0" + num;
			}
		}else if (num.length() > 10){
			num = num.substring(num.length() - 10, num.length());
		}
		return num;
	}
	
	/**
	 * 产生不包括新文件在内的 路径
	 * @param fileName 新文件名（10位随机数）
	 * @param realFilePath 路径
	 * @return 新的文件所在的路径
	 */
	protected String getMenuFilePath(String fileName,String realFilePath){
		String path = realFilePath;
		String folder = "";
		if (fileName.length() ==10){
			for (int index = 0 ; index < fileName.length() ; index = index + 2){
				folder = fileName.substring(index, index + 2);
				path = path + "/" + folder;
				File file = new File(path);
				if (!file.exists()){
					file.mkdir();
				}
			}
		}
		return path;
	}
	
	/**
	 * 得到真实的路径
	 * @return 真实的路径
	 */
	protected String getRealFilePath(){
		return this.getRealFilePath(null).getRealPath();
	}
	
	/**
	 * 得到真实的路径
	 * @param model 模块路径
	 * @return 路径
	 */
	protected UploadPathObj getRealFilePath(String model){
		String rootPath = null;
		String relativePath = null;
		if (null == model || "".equals(model)){
			relativePath = "upload" ;
			rootPath = Config.getString("upload.path") + "/" + "upload" ;
		}else{
			relativePath = "upload" + "/" + model ;
			rootPath = Config.getString("upload.path") + "/" + "upload" + "/" + model ;
		}
		File file = new File(rootPath);
		if (!file.exists()){
			file.mkdir();
		}
		Calendar cal = Calendar.getInstance();
		String year = String.valueOf(cal.get(Calendar.YEAR));
		String month = String.valueOf(cal.get(Calendar.MONTH) + 1);
		String day = String.valueOf(cal.get(Calendar.DAY_OF_MONTH));
		file = new File(rootPath + "/" + year);
		if (!file.exists()){
			file.mkdir();
		}
		file = new File(rootPath + "/" + year + "/" + month);
		if (!file.exists()){
			file.mkdir();
		}
		file = new File(rootPath + "/" + year + "/" + month + "/" + day);
		if (!file.exists()){
			file.mkdir();
		}
		UploadPathObj pathObj = new UploadPathObj();
		pathObj.setRealPath(rootPath + "/" + year + "/" + month + "/" + day);
		pathObj.setRelativePath(relativePath + "/" + year + "/" + month + "/" + day);
		
		return pathObj;
	}
	
	/**
	 * 路径转换
	 */
	private String tansferPath(String path){
		return path.replaceAll("\\\\", "/");
		
	}
}
